# -*- coding: utf-8 -*-
"""
节假日数据管理
包含中国法定节假日和调休安排
"""

from datetime import date, datetime
from typing import Dict, List, Set
import chinese_calendar

class HolidayManager:
    """节假日管理器"""
    
    def __init__(self):
        """初始化节假日管理器"""
        # chinese_calendar支持的年份范围
        self.chinese_calendar_years = (2004, 2023)
        
        # 扩展的节假日数据（2024年及以后）
        self.extended_holidays = {
            2024: {
                # 元旦
                (1, 1): "元旦",
                # 春节（示例，需要根据实际调整）
                (2, 10): "春节", (2, 11): "春节", (2, 12): "春节", 
                (2, 13): "春节", (2, 14): "春节", (2, 15): "春节", (2, 16): "春节",
                # 清明节
                (4, 4): "清明节", (4, 5): "清明节", (4, 6): "清明节",
                # 劳动节
                (5, 1): "劳动节", (5, 2): "劳动节", (5, 3): "劳动节", (5, 4): "劳动节", (5, 5): "劳动节",
                # 端午节
                (6, 10): "端午节",
                # 中秋节
                (9, 17): "中秋节",
                # 国庆节
                (10, 1): "国庆节", (10, 2): "国庆节", (10, 3): "国庆节", 
                (10, 4): "国庆节", (10, 5): "国庆节", (10, 6): "国庆节", (10, 7): "国庆节",
            },
            2025: {
                # 元旦
                (1, 1): "元旦",
                # 春节（2025年1月29日）
                (1, 28): "春节", (1, 29): "春节", (1, 30): "春节", 
                (1, 31): "春节", (2, 1): "春节", (2, 2): "春节", (2, 3): "春节", (2, 4): "春节",
                # 清明节（2025年4月5日）
                (4, 5): "清明节", (4, 6): "清明节", (4, 7): "清明节",
                # 劳动节（2025年5月1日）
                (5, 1): "劳动节", (5, 2): "劳动节", (5, 3): "劳动节", (5, 4): "劳动节", (5, 5): "劳动节",
                # 端午节（2025年5月31日）
                (5, 31): "端午节", (6, 1): "端午节", (6, 2): "端午节",
                # 中秋节+国庆节（2025年10月1-8日）
                (10, 1): "国庆节+中秋节", (10, 2): "国庆节+中秋节", (10, 3): "国庆节+中秋节", 
                (10, 4): "国庆节+中秋节", (10, 5): "国庆节+中秋节", (10, 6): "国庆节+中秋节", 
                (10, 7): "国庆节+中秋节", (10, 8): "国庆节+中秋节",
            },
            2026: {
                # 基础节假日（需要根据实际政府通知调整）
                (1, 1): "元旦",
                (10, 1): "国庆节", (10, 2): "国庆节", (10, 3): "国庆节", 
                (10, 4): "国庆节", (10, 5): "国庆节", (10, 6): "国庆节", (10, 7): "国庆节",
            },
            2027: {
                (1, 1): "元旦",
                (10, 1): "国庆节", (10, 2): "国庆节", (10, 3): "国庆节", 
                (10, 4): "国庆节", (10, 5): "国庆节", (10, 6): "国庆节", (10, 7): "国庆节",
            },
            2028: {
                (1, 1): "元旦",
                (10, 1): "国庆节", (10, 2): "国庆节", (10, 3): "国庆节", 
                (10, 4): "国庆节", (10, 5): "国庆节", (10, 6): "国庆节", (10, 7): "国庆节",
            },
        }
        
        # 调休工作日（原本是周末但要上班的日子）
        self.extended_workdays = {
            2025: {
                (1, 26): "春节调休", (2, 8): "春节调休",  # 春节调休
                (4, 27): "劳动节调休",  # 劳动节调休
                (9, 28): "国庆节调休", (10, 11): "国庆节调休",  # 国庆节调休
            }
        }
    
    def is_holiday(self, date_obj) -> bool:
        """判断是否为节假日"""
        try:
            # 获取日期
            if isinstance(date_obj, datetime):
                check_date = date_obj.date()
            elif isinstance(date_obj, date):
                check_date = date_obj
            elif hasattr(date_obj, 'date'):
                check_date = date_obj.date()
            elif hasattr(date_obj, 'year'):
                check_date = date(date_obj.year, date_obj.month, date_obj.day)
            else:
                return False
            
            year = check_date.year
            month_day = (check_date.month, check_date.day)
            
            # 首先检查是否为调休工作日
            if year in self.extended_workdays:
                if month_day in self.extended_workdays[year]:
                    return False  # 调休工作日不是节假日
            
            # 使用chinese_calendar库（支持2004-2023）
            if self.chinese_calendar_years[0] <= year <= self.chinese_calendar_years[1]:
                return chinese_calendar.is_holiday(check_date)
            
            # 使用扩展数据
            if year in self.extended_holidays:
                return month_day in self.extended_holidays[year]
            
            # 未知年份，返回False
            return False
            
        except Exception:
            return False
    
    def get_holiday_name(self, date_obj) -> str:
        """获取节假日名称"""
        try:
            if isinstance(date_obj, datetime):
                check_date = date_obj.date()
            elif isinstance(date_obj, date):
                check_date = date_obj
            elif hasattr(date_obj, 'date'):
                check_date = date_obj.date()
            elif hasattr(date_obj, 'year'):
                check_date = date(date_obj.year, date_obj.month, date_obj.day)
            else:
                return ""
            
            year = check_date.year
            month_day = (check_date.month, check_date.day)
            
            # 检查扩展数据
            if year in self.extended_holidays:
                if month_day in self.extended_holidays[year]:
                    return self.extended_holidays[year][month_day]
            
            # 使用chinese_calendar库
            if self.chinese_calendar_years[0] <= year <= self.chinese_calendar_years[1]:
                if chinese_calendar.is_holiday(check_date):
                    return "节假日"
            
            return ""
            
        except Exception:
            return ""
    
    def is_workday(self, date_obj) -> bool:
        """判断是否为工作日（非周末且非节假日，或调休工作日）"""
        try:
            if isinstance(date_obj, datetime):
                check_date = date_obj.date()
                weekday = date_obj.weekday()
            elif isinstance(date_obj, date):
                check_date = date_obj
                weekday = date_obj.weekday()
            elif hasattr(date_obj, 'date'):
                check_date = date_obj.date()
                weekday = date_obj.weekday()
            elif hasattr(date_obj, 'year'):
                check_date = date(date_obj.year, date_obj.month, date_obj.day)
                weekday = check_date.weekday()
            else:
                return False
            
            year = check_date.year
            month_day = (check_date.month, check_date.day)
            
            # 检查是否为调休工作日
            if year in self.extended_workdays:
                if month_day in self.extended_workdays[year]:
                    return True  # 调休工作日
            
            # 周末不是工作日（除非是调休）
            if weekday >= 5:  # 周六或周日
                return False
            
            # 节假日不是工作日
            if self.is_holiday(date_obj):
                return False
            
            # 其他情况为工作日
            return True
            
        except Exception:
            # 出错时按基础逻辑判断
            weekday = date_obj.weekday() if hasattr(date_obj, 'weekday') else date_obj.date().weekday()
            return weekday < 5
    
    def get_supported_years(self) -> tuple:
        """获取支持的年份范围"""
        min_year = min(self.chinese_calendar_years[0], min(self.extended_holidays.keys()))
        max_year = max(self.chinese_calendar_years[1], max(self.extended_holidays.keys()))
        return (min_year, max_year)
